import { LockService } from './lock.service';
import {
    Injectable,
    RequestTimeoutException,
    Inject,
    forwardRef,
} from '@nestjs/common';
import * as Redis from 'ioredis';

@Injectable()
export class RedisService {
    constructor(
        @Inject(forwardRef(() => LockService))
        private readonly lockService: LockService,
    ) {}

    static REDIS_CONFIG = {
        port: 6379,
        host: '127.0.0.1',
        password: '123456',
        // 重新连接之后自动subscribe
        autoResubscribe: true,
        db: 0,
    };

    // private redisClentFactory = (db: number) =>{
    //     let redis = new Redis({
    //         ...RedisService.REDIS_CONFIG,
    //         // db,
    //     });
    //     console.log('=====redis=====');
    //     console.log(redis);
    //     console.log('=====redis=====');
    //     return redis
    // }
    // private redisClentFactory = (db: number) => {
    //     return this.linkRedis(db)
    // }
    private linkRedis(db: number) {
        let redis = new Redis({
            ...RedisService.REDIS_CONFIG,
            db,
        });
        // console.log('=====redis=====');
        // console.log(redis);
        // console.log('=====redis=====');
        return redis;
    }

    private dataRedis = null;

    private subscribeRedis = null;
    private publishRedis = null;

    /**
     * 当前进程的redis client
     */
    subscribeRedisClient() {
        if (!this.subscribeRedis) {
            let res = this.linkRedis(2);
            this.subscribeRedis = res;
            // console.log('=====this.subscribeRedis=====');
            // console.log(this.subscribeRedis);
            // console.log('=====this.subscribeRedis=====');
        }

        return this.subscribeRedis;
    }

    publishRedisClient() {
        if (!this.publishRedis) {
            let res = this.linkRedis(2);
            this.publishRedis = res;
            // console.log('=====this.publishRedis=====');
            // console.log(this.publishRedis);
            // console.log('=====this.publishRedis=====');
        }
        return this.publishRedis;
    }

    dataRedisClient() {
        if (!this.dataRedis) {
            let res = this.linkRedis(0);
            this.dataRedis = res;
            // console.log('=====this.dataRedis=====');
            // console.log(this.dataRedis);
            // console.log('=====this.dataRedis=====');
        }
        return this.dataRedis;
    }

    /**
     * key: redis键名
     * ttl: 过期时间，单位为s
     * value: 保存的值，必须是plain data, 里面不包含函数
     */
    getDataByKeyOrFunction<T>(opts: {
        key: string;
        // 过期时间 单位是s
        ttl?: number;
        fun: () => T | Promise<T>;
    }): Promise<T> {
        return this.lockService.runTransaction(opts.key, async () => {
            let data = await this.dataRedis.get(opts.key);
            if (data) {
                // 已经有缓存
                return JSON.parse(data);
            }
            let ret = await opts.fun();
            let json = JSON.stringify(ret);
            // 存到Redis里面
            if (opts.ttl) {
                await this.dataRedis.setex(opts.key, opts.ttl, json);
            } else {
                await this.dataRedis.set(opts.key, json);
            }
            return ret;
        });
    }

    /**
     * 从redis中删除key
     */
    async removeKey(...keys: string[]) {
        return this.dataRedis.del(...keys);
    }
}
